package com.sdp.right.excel.importExcel;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.poi.ss.formula.functions.T;
import org.springframework.util.StringUtils;

import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.IService;
import com.sdp.core.bizc.db.QueryUtil;
import com.sdp.core.bizc.vo.BusinessContext;
import com.sdp.right.db.sys_dict.service.ISysDictService;
import com.sdp.right.entity.SysImportTemplateDetail;

public class ImportListener extends AnalysisEventListener<Map<Integer, String>> {

	private static final int BATCH_COUNT = 500;
	
	List<T> rowDataList = new ArrayList<>();
	List<T> insertList = new ArrayList<>();
	List<T> updateList = new ArrayList<>();
	
	private IService<T> serviceImpl =null;
	
	private List<SysImportTemplateDetail> templateDetailList=null;
	
	private Class<T> entityClass = null;
	
	private BusinessContext businessContext;
	
	private Map<String,Map<String,String>> dictInfo;
	
	private ISysDictService iSysDictService;
	
	private ImportExcelRowCallbackService rowCallbackService;
	
	public ImportListener(Class<T> entityClass,IService<T> serviceImpl,List<SysImportTemplateDetail> templateDetailList,Map<String,Map<String,String>> dictInfo,ISysDictService iSysDictService,ImportExcelRowCallbackService rowCallbackService,BusinessContext businessContext) {
		this.serviceImpl = serviceImpl;
		this.templateDetailList = templateDetailList;
		this.entityClass = entityClass;
		this.businessContext = businessContext;
		this.dictInfo = dictInfo;
		this.iSysDictService = iSysDictService;
		this.rowCallbackService = rowCallbackService;
	}
	
	@Override
	public void invoke(Map<Integer, String> data, AnalysisContext context) {
		if(!businessContext.isSuccess()) {
			return;
		}
		
		JSONObject row = new JSONObject();
		for(int i = 0, n = templateDetailList.size(); i < n; i++) {
			SysImportTemplateDetail sitd = templateDetailList.get(i);
			if(!data.containsKey(i) || StringUtils.isEmpty(data.get(i))) {
				row.put(sitd.getFieldName(),null);
				continue;
			}
			//判断是否为下拉,下拉数据源有值，并且字段属性是字符
			if(!StringUtils.isEmpty(sitd.getDictCode()) && "class java.lang.String".equals(sitd.getFieldType())) {
				row.put(sitd.getFieldName(),QueryUtil.typeConvert(sitd.getFieldType(),  formatDict(sitd, data.get(i))));
			}else {
				row.put(sitd.getFieldName(),QueryUtil.typeConvert(sitd.getFieldType(),  data.get(i)));
			}
		}
		
		rowDataList.add(JSON.parseObject(JSON.toJSONString(row), entityClass));
		//如果有行回调，则执行行回到函数
		if(rowCallbackService != null) {
			rowCallbackService.execute(rowDataList.get(rowDataList.size() - 1), insertList, updateList, templateDetailList, context);
		} else {
			insertList.add(rowDataList.get(rowDataList.size() - 1));
		}
		
		if (rowDataList.size() >= BATCH_COUNT) {
			processBatch(context);
		}
	}
	
	protected void processBatch(AnalysisContext context) {
		//如果有行回调，则执行行回到函数
		if(rowCallbackService != null) {
			rowCallbackService.executeBatch(rowDataList, insertList, updateList, templateDetailList, context);
		}
		if (insertList.size() > 0) {
			if(!serviceImpl.saveBatch(insertList)) {
				businessContext.setMessage("数据保存失败，请确认EXCEL数据是否合法");
				businessContext.setSuccess(false);
			}
		}
		if (updateList.size() > 0) {
			if(!serviceImpl.updateBatchById(updateList)) {
				businessContext.setMessage("数据更新失败，请确认EXCEL数据是否合法");
				businessContext.setSuccess(false);
			}
		}
		
		rowDataList.clear();
		insertList.clear();
		updateList.clear();
	}
	
	public String formatDict(SysImportTemplateDetail sitd,String fieldValue) {
		if(StringUtils.isEmpty(sitd.getItemText()) || StringUtils.isEmpty(sitd.getItemValue())) {
			businessContext.setMessage("模板中"+sitd.getFieldTitle()+" 对应的下拉标题和值字段未设置");
			businessContext.setSuccess(false);
			return fieldValue;
		}
		
		
		if(!dictInfo.containsKey(sitd.getDictCode())) {
			//得到下拉信息
			List<Object> dictList = iSysDictService.getDictInfo(sitd.getDictCode(), new String[] {});
			if(dictList==null || dictList.size()==0) {
				businessContext.setMessage(sitd.getFieldTitle()+" 设置的下拉数据源数据不存在");
				businessContext.setSuccess(false);
				return fieldValue;
			}
			
			//将下拉数据源转为MAP
			Map<String,String> dictMap = new HashMap<String, String>();
			filterDictText(dictMap,dictList, fieldValue, sitd.getItemText(), sitd.getItemValue());
			dictInfo.put(sitd.getDictCode(), dictMap);
		}
		
		if(dictInfo.get(sitd.getDictCode()).containsKey(fieldValue)) {
			return dictInfo.get(sitd.getDictCode()).get(fieldValue);
		}else {
			businessContext.setMessage(sitd.getFieldTitle()+" 的值 ["+fieldValue+"] 在对应的下拉数据源中未找到，请核对");
			businessContext.setSuccess(false);
			return fieldValue;
		}
	}
	
	public void filterDictText(Map<String,String> dictMap,List<Object> dictList,String fieldValue,String itexText,String itexValue) {
		JSONObject dictObj = null;
		for(int i=0; i<dictList.size();i++) {
			dictObj = JSONObject.parseObject(JSON.toJSONString(dictList.get(i)));
			dictMap.put(dictObj.getString(itexText), dictObj.getString(itexValue));
			if(dictObj.containsKey("children")) {
				//如果是树
				filterDictText(dictMap, dictObj.getJSONArray("children"), fieldValue, itexText, itexValue);
			}
		}
	}

	@Override
	public void doAfterAllAnalysed(AnalysisContext context) {
		if (rowDataList.size() > 0) {
			processBatch(context);
		}
	}

}
